﻿using HalconDotNet;
using System.Windows.Forms;
using Prism.Commands;
using Prism.Ioc;
using Prism.Services.Dialogs;
using System;
using System.Collections.ObjectModel;
using ViewROI;
using CCSFeederCameraUI2.Services;
using System.Threading.Tasks;
using System.Threading;
using CCSFeederCameraUI2.Data.Extensions;
using CCSFeederCameraUI2.Models;
using NLog;
using System.Data.Common;
using System.IO;
using HalconViewer;
using Prism.Regions;
using CCSFeederCameraUI2.Data.MClass;
using CCSFeederCameraUI2.Data;
using System.Linq;
using CCSFeederCameraUI2.Data.ViewModels;
using System.Runtime.InteropServices;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using System.Drawing;

namespace CCSFeederCameraUI2.ViewModels.Dialogs
{
    public class CameraVisionDialogViewModel : DialogViewModel
    {
        [DllImport("halcon.dll")]
        static extern void HIOCancelDraw();//退出画操作时，调用此函数
        #region 变量
        string partNum = string.Empty;
        int handIndex = 0;
        private readonly IContainerProvider _containerProvider;
        private readonly DrawROI drawROI;
        private ICameraService _camera;
        private HObject mimage;
        private string constr = string.Empty;
        private bool isChanged = false;
        private bool isClosing = false;
        #endregion
        #region 属性
        #region halcon
        private HImage cameraImage0;
        public HImage CameraImage0
        {
            get { return cameraImage0; }
            set { SetProperty(ref cameraImage0, value); }
        }
        private bool cameraRepaint0;
        public bool CameraRepaint0
        {
            get { return cameraRepaint0; }
            set { SetProperty(ref cameraRepaint0, value); }
        }
        private ObservableCollection<ROI> cameraROIList0 = new ObservableCollection<ROI>();
        public ObservableCollection<ROI> CameraROIList0
        {
            get { return cameraROIList0; }
            set { SetProperty(ref cameraROIList0, value); }
        }

        private HObject cameraAppendHObject0;
        public HObject CameraAppendHObject0
        {
            get { return cameraAppendHObject0; }
            set { SetProperty(ref cameraAppendHObject0, value); }
        }
        private HMsgEntry cameraAppendHMessage0;
        public HMsgEntry CameraAppendHMessage0
        {
            get { return cameraAppendHMessage0; }
            set { SetProperty(ref cameraAppendHMessage0, value); }
        }
        private Tuple<string, object> cameraGCStyle0;
        public Tuple<string, object> CameraGCStyle0
        {
            get { return cameraGCStyle0; }
            set { SetProperty(ref cameraGCStyle0, value); }
        }
        private bool isCameraReady;
        public bool IsCameraReady
        {
            get { return isCameraReady; }
            set { SetProperty(ref isCameraReady, value); }
        }
        #endregion
        private int maxGrayDark;
        public int MaxGrayDark
        {
            get { return maxGrayDark; }
            set
            {
                if (value >= 0 && value <= 255)
                {
                    SetProperty(ref maxGrayDark, value);
                }
            }
        }
        private int minGrayLight;
        public int MinGrayLight
        {
            get { return minGrayLight; }
            set
            {
                if (value >= 0 && value <= 255)
                {
                    SetProperty(ref minGrayLight, value);
                }
            }
        }
        private double brightAreaMin;
        public double BrightAreaMin
        {
            get { return brightAreaMin; }
            set
            {
                if (value >= 0 && value <= 1)
                {
                    SetProperty(ref brightAreaMin, value);
                }
            }
        }
        private double darkAreaMin;
        public double DarkAreaMin
        {
            get { return darkAreaMin; }
            set
            {
                if (value >= 0 && value <= 1)
                {
                    SetProperty(ref darkAreaMin, value);
                }
            }
        }
        private bool isBusy;
        public bool IsBusy
        {
            get { return isBusy; }
            set { SetProperty(ref isBusy, value); }
        }
        private bool isDrawing;
        public bool IsDrawing
        {
            get { return isDrawing; }
            set { SetProperty(ref isDrawing, value); }
        }
        private ObservableCollection<DrawROIOperateDisp> drawROIOperateList = new ObservableCollection<DrawROIOperateDisp>();
        public ObservableCollection<DrawROIOperateDisp> DrawROIOperateList
        {
            get { return drawROIOperateList; }
            set { SetProperty(ref drawROIOperateList, value); }
        }
        private int drawROIOperateListSelectedIndex;
        public int DrawROIOperateListSelectedIndex
        {
            get { return drawROIOperateListSelectedIndex; }
            set { SetProperty(ref drawROIOperateListSelectedIndex, value); }
        }
        private int regionColorKind;
        public int RegionColorKind
        {
            get { return regionColorKind; }
            set { SetProperty(ref regionColorKind, value); }
        }
        #endregion
        #region 命令
        private DelegateCommand openImageCommand;
        public DelegateCommand OpenImageCommand =>
            openImageCommand ?? (openImageCommand = new DelegateCommand(ExecuteOpenImageCommand));
        private DelegateCommand grabImageCommand;
        public DelegateCommand GrabImageCommand =>
            grabImageCommand ?? (grabImageCommand = new DelegateCommand(ExecuteGrabImageCommand));
        private DelegateCommand testCommand;
        public DelegateCommand TestCommand =>
            testCommand ?? (testCommand = new DelegateCommand(ExecuteTestCommand));
        private DelegateCommand setAsStandardCommand;
        public DelegateCommand SetAsStandardCommand =>
            setAsStandardCommand ?? (setAsStandardCommand = new DelegateCommand(ExecuteSetAsStandardCommand));
        private DelegateCommand createRoiCommand;
        public DelegateCommand CreateRoiCommand =>
            createRoiCommand ?? (createRoiCommand = new DelegateCommand(ExecuteCreateRoiCommand));
        private DelegateCommand<object> textBoxLostFocusCommand;
        public DelegateCommand<object> TextBoxLostFocusCommand =>
            textBoxLostFocusCommand ?? (textBoxLostFocusCommand = new DelegateCommand<object>(ExecuteTextBoxLostFocusCommand));
        private DelegateCommand<object> drawRectangleCommand;
        public DelegateCommand<object> DrawRectangleCommand =>
            drawRectangleCommand ?? (drawRectangleCommand = new DelegateCommand<object>(ExecuteDrawRectangleCommand));
        private DelegateCommand<object> drawCircleCommand;
        public DelegateCommand<object> DrawCircleCommand =>
            drawCircleCommand ?? (drawCircleCommand = new DelegateCommand<object>(ExecuteDrawCircleCommand));
        private DelegateCommand<object> drawRegionCommand;
        public DelegateCommand<object> DrawRegionCommand =>
            drawRegionCommand ?? (drawRegionCommand = new DelegateCommand<object>(ExecuteDrawRegionCommand));
        private DelegateCommand deleteDrawCommand;
        public DelegateCommand DeleteDrawCommand =>
            deleteDrawCommand ?? (deleteDrawCommand = new DelegateCommand(ExecuteDeleteDrawCommand));
        private DelegateCommand<object> regionColorSelectCommand;
        public DelegateCommand<object> RegionColorSelectCommand =>
            regionColorSelectCommand ?? (regionColorSelectCommand = new DelegateCommand<object>(ExecuteRegionColorSelectCommand));

        void ExecuteRegionColorSelectCommand(object obj)
        {
            RegionColorKind = int.Parse(obj.ToString());
            LoadRegionInit();
        }
        void ExecuteDeleteDrawCommand()
        {
            if (CameraImage0 != null)
            {
                string _color = string.Empty, _regName = string.Empty,dispName = string.Empty;
                switch (RegionColorKind)
                {
                    case 0:
                        _color = "blue";
                        _regName = "Rec1";
                        dispName = "亮色";
                        break;
                    case 1:
                        _color = "reg";
                        _regName = "Rec2";
                        dispName = "暗色";
                        break;
                    default:
                        break;
                }
                if (MessageBox.Show($"确认要删除\"{dispName}\"吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
                {
                    isChanged = true;
                    try
                    {
                        CameraAppendHObject0 = null;
                        CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                        
                        CameraGCStyle0 = new Tuple<string, object>("Color", _color);
                        string dirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, partNum, $"Camera\\{handIndex}");
                        Directory.CreateDirectory(dirPath);
                        HObject rec1;
                        HOperatorSet.GenEmptyRegion(out rec1);
                        HOperatorSet.WriteRegion(rec1, System.IO.Path.Combine(dirPath, $"{_regName}.hobj"));

                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
            else
            {
                MessageBox.Show("图像为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        void ExecuteDrawRegionCommand(object obj)
        {
            if (CameraImage0 != null)
            {
                isChanged = true;
                try
                {
                    CameraAppendHObject0 = null;
                    CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                    string _color = string.Empty, _regName = string.Empty;
                    switch (RegionColorKind)
                    {
                        case 0:
                            _color = "blue";
                            _regName = "Rec1";
                            break;
                        case 1:
                            _color = "reg";
                            _regName = "Rec2";
                            break;
                        default:
                            break;
                    }
                    CameraGCStyle0 = new Tuple<string, object>("Color", _color);
                    string dirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, partNum, $"Camera\\{handIndex}");
                    Directory.CreateDirectory(dirPath);
                    HObject rec1;
                    HOperatorSet.GenEmptyRegion(out rec1);
                    if (File.Exists(System.IO.Path.Combine(dirPath, "Rec1.hobj")))
                    {
                        HOperatorSet.ReadRegion(out rec1, System.IO.Path.Combine(dirPath, $"{_regName}.hobj"));
                        CameraAppendHObject0 = rec1.CopyObj(1, -1);
                    }
                    IsDrawing = true;
                    var roi = drawROI.imageViewer.DrawROI(ROI.ROI_TYPE_REGION);
                    IsDrawing = false;
                    if (!isClosing)
                    {
                        var region = roi.getRegion();
                        if (obj is DrawROIOperateDisp disp)
                        {
                            switch (disp.OperateName)
                            {
                                case "合并":
                                    HOperatorSet.Union2(rec1, region, out rec1);
                                    break;
                                case "交集":
                                    HOperatorSet.Intersection(rec1, region, out rec1);
                                    break;
                                case "差集":
                                    HOperatorSet.Difference(rec1, region, out rec1);
                                    break;
                                case "XOR":
                                    HOperatorSet.SymmDifference(rec1, region, out rec1);
                                    break;
                                default:
                                    break;
                            }
                        }
                        CameraAppendHObject0 = null;
                        CameraAppendHObject0 = rec1.CopyObj(1, -1);

                        HOperatorSet.WriteRegion(rec1, System.IO.Path.Combine(dirPath, $"{_regName}.hobj"));
                        rec1.Dispose();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show("图像为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        void ExecuteDrawCircleCommand(object obj)
        {
            if (CameraImage0 != null)
            {
                isChanged = true;
                try
                {
                    CameraAppendHObject0 = null;
                    CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                    string _color = string.Empty, _regName = string.Empty;
                    switch (RegionColorKind)
                    {
                        case 0:
                            _color = "blue";
                            _regName = "Rec1";
                            break;
                        case 1:
                            _color = "reg";
                            _regName = "Rec2";
                            break;
                        default:
                            break;
                    }
                    CameraGCStyle0 = new Tuple<string, object>("Color", _color);
                    string dirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, partNum, $"Camera\\{handIndex}");
                    Directory.CreateDirectory(dirPath);
                    HObject rec1;
                    HOperatorSet.GenEmptyRegion(out rec1);
                    if (File.Exists(System.IO.Path.Combine(dirPath, "Rec1.hobj")))
                    {
                        HOperatorSet.ReadRegion(out rec1, System.IO.Path.Combine(dirPath, $"{_regName}.hobj"));
                        CameraAppendHObject0 = rec1.CopyObj(1, -1);
                    }
                    IsDrawing = true;
                    var roi = drawROI.imageViewer.DrawROI(ROI.ROI_TYPE_CIRCLE);
                    IsDrawing = false;
                    if (!isClosing)
                    {
                        var region = roi.getRegion();
                        if (obj is DrawROIOperateDisp disp)
                        {
                            switch (disp.OperateName)
                            {
                                case "合并":
                                    HOperatorSet.Union2(rec1, region, out rec1);
                                    break;
                                case "交集":
                                    HOperatorSet.Intersection(rec1, region, out rec1);
                                    break;
                                case "差集":
                                    HOperatorSet.Difference(rec1, region, out rec1);
                                    break;
                                case "XOR":
                                    HOperatorSet.SymmDifference(rec1, region, out rec1);
                                    break;
                                default:
                                    break;
                            }
                        }
                        CameraAppendHObject0 = null;
                        CameraAppendHObject0 = rec1.CopyObj(1, -1);

                        HOperatorSet.WriteRegion(rec1, System.IO.Path.Combine(dirPath, $"{_regName}.hobj"));
                        rec1.Dispose();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show("图像为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        void ExecuteDrawRectangleCommand(object obj)
        {
            if (CameraImage0 != null)
            {
                isChanged = true;
                try
                {
                    CameraAppendHObject0 = null;
                    CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                    string _color = string.Empty,_regName = string.Empty;
                    switch (RegionColorKind)
                    {
                        case 0:
                            _color = "blue";
                            _regName = "Rec1";
                            break;
                        case 1:
                            _color = "reg";
                            _regName = "Rec2";
                            break;
                        default:
                            break;
                    }

                    CameraGCStyle0 = new Tuple<string, object>("Color", _color);
                    string dirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, partNum, $"Camera\\{handIndex}");
                    Directory.CreateDirectory(dirPath);
                    HObject rec1;
                    HOperatorSet.GenEmptyRegion(out rec1);
                    if (File.Exists(System.IO.Path.Combine(dirPath, $"{_regName}.hobj")))
                    {
                        HOperatorSet.ReadRegion(out rec1, System.IO.Path.Combine(dirPath, $"{_regName}.hobj"));
                        CameraAppendHObject0 = rec1.CopyObj(1, -1);
                    }
                    IsDrawing = true;
                    var roi = drawROI.imageViewer.DrawROI(ROI.ROI_TYPE_RECTANGLE1);
                    IsDrawing = false;
                    if (!isClosing)
                    {
                        var region = roi.getRegion();
                        if (obj is DrawROIOperateDisp disp)
                        {
                            switch (disp.OperateName)
                            {
                                case "合并":
                                    HOperatorSet.Union2(rec1, region, out rec1);
                                    break;
                                case "交集":
                                    HOperatorSet.Intersection(rec1, region, out rec1);
                                    break;
                                case "差集":
                                    HOperatorSet.Difference(rec1, region, out rec1);
                                    break;
                                case "XOR":
                                    HOperatorSet.SymmDifference(rec1, region, out rec1);
                                    break;
                                default:
                                    break;
                            }
                        }
                        CameraAppendHObject0 = null;
                        CameraAppendHObject0 = rec1.CopyObj(1, -1);

                        HOperatorSet.WriteRegion(rec1, System.IO.Path.Combine(dirPath, $"{_regName}.hobj"));
                        rec1.Dispose();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show("图像为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        void ExecuteTextBoxLostFocusCommand(object obj)
        {
            if (obj is string str)
            {
                isChanged = true;
                try
                {
                    switch (str)
                    {
                        case "MaxGrayDark":
                            {
                                using var mdb = new MDbContext();
                                var _param = mdb.MParams.FirstOrDefault(p => p.Name == "MaxGrayDark" && p.Hand == handIndex && p.PartNum == partNum);
                                if (_param != null)
                                {
                                    _param.Value = MaxGrayDark.ToString();
                                    mdb.SaveChanges();
                                }
                            }
                            break;
                        case "MinGrayLight":
                            {
                                using var mdb = new MDbContext();
                                var _param = mdb.MParams.FirstOrDefault(p => p.Name == "MinGrayLight" && p.Hand == handIndex && p.PartNum == partNum);
                                if (_param != null)
                                {
                                    _param.Value = MinGrayLight.ToString();
                                    mdb.SaveChanges();
                                }
                            }
                            break;
                        case "BrightAreaMin":
                            {
                                using var mdb = new MDbContext();
                                var _param = mdb.MParams.FirstOrDefault(p => p.Name == "BrightAreaMin" && p.Hand == handIndex && p.PartNum == partNum);
                                if (_param != null)
                                {
                                    _param.Value = BrightAreaMin.ToString();
                                    mdb.SaveChanges();
                                }
                            }
                            break;
                        case "DarkAreaMin":
                            {
                                using var mdb = new MDbContext();
                                var _param = mdb.MParams.FirstOrDefault(p => p.Name == "DarkAreaMin" && p.Hand == handIndex && p.PartNum == partNum);
                                if (_param != null)
                                {
                                    _param.Value = DarkAreaMin.ToString();
                                    mdb.SaveChanges();
                                }
                            }
                            break;
                        default:
                            break;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

            }
        }
        void ExecuteCreateRoiCommand()
        {
            if (CameraImage0 != null)
            {
                if (MessageBox.Show($"确认要设画识别区域吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
                {
                    isChanged = true;
                    try
                    {
                        CameraAppendHObject0 = null;
                        IsDrawing = true;
                        var roi = drawROI.imageViewer.DrawROI(ROI.ROI_TYPE_RECTANGLE2);
                        IsDrawing = false;
                        if (!isClosing)
                        {
                            var region = roi.getRegion();
                            CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                            CameraGCStyle0 = new Tuple<string, object>("Color", "yellow");
                            CameraAppendHObject0 = region;
                            string dirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, partNum, $"Camera\\{handIndex}");
                            Directory.CreateDirectory(dirPath);
                            HOperatorSet.WriteRegion(region, System.IO.Path.Combine(dirPath, "Rec1.hobj"));
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
            else
            {
                MessageBox.Show("图像为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        void ExecuteSetAsStandardCommand()
        {
            if (CameraImage0 != null)
            {
                if (MessageBox.Show($"确认要设为基准吗？", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
                {
                    isChanged = true;
                    try
                    {
                        string dirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, partNum, $"Camera\\{handIndex}");
                        Directory.CreateDirectory(dirPath);
                        HOperatorSet.WriteImage(CameraImage0, "jpeg", 0, Path.Combine(dirPath, $"{DateTime.Now:yyyyMMdd_HHmmss}.jpg"));
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    //HOperatorSet.WriteRegion(r_region, System.IO.Path.Combine(dirPath, "ST_Region.hobj"));
                }
            }
            else
            {
                MessageBox.Show("图像为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        void ExecuteTestCommand()
        {
            if (CameraImage0 != null)
            {
                IsBusy = true;

                try
                {
                    CameraAppendHObject0 = null;
                    CameraAppendHMessage0 = null;
                    Task.Run(() =>
                    {
                        string dirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, partNum, $"Camera\\{handIndex}");
                        Directory.CreateDirectory(dirPath);
                        bool r1 = false, r2 = false; HObject r_region;
                        HOperatorSet.GenEmptyRegion(out r_region);
                        HOperatorSet.ReadRegion(out var rec1, System.IO.Path.Combine(dirPath, "Rec1.hobj"));
                        HOperatorSet.ReadRegion(out var rec2, System.IO.Path.Combine(dirPath, "Rec2.hobj"));
                        HOperatorSet.Decompose3(CameraImage0,out var Red,out var Green,out var Blue);
                        HOperatorSet.ReduceDomain(Blue, rec1, out var imageReduced);
                        HOperatorSet.Threshold(imageReduced, out var bright, 0, MinGrayLight);
                        HOperatorSet.CountObj(bright,out var number);
                        double brightp = 0;
                        if (number > 0)
                        {
                            HOperatorSet.Union2(r_region, bright, out r_region);
                            HOperatorSet.RegionFeatures(bright, "area", out var area);
                            HOperatorSet.RegionFeatures(rec1, "area", out var rec1area);
                            brightp = area.D / rec1area.D;
                            if (brightp >= BrightAreaMin)
                            {
                                r1 = false;
                            }
                            else
                            {
                                r1 = true;
                            }
                        }
                        else
                        {
                            r1 = true;
                        }

                        HOperatorSet.ReduceDomain(Blue, rec2, out imageReduced);
                        HOperatorSet.Threshold(imageReduced, out var dark, MaxGrayDark, 255);
                        HOperatorSet.CountObj(bright, out number);
                        double dartp = 0;
                        if (number > 0)
                        {
                            HOperatorSet.Union2(r_region, dark, out r_region);
                            HOperatorSet.RegionFeatures(dark, "area", out var area);
                            HOperatorSet.RegionFeatures(rec2, "area", out var rec2area);
                            dartp = area.D / rec2area.D;
                            if (dartp >= DarkAreaMin)
                            {
                                r2 = false;
                            }
                            else
                            {
                                r2 = true;
                            }
                        }
                        else
                        {
                            r2 = true;
                        }
                        imageReduced.Dispose();
                        Red.Dispose();
                        Green.Dispose();
                        Blue.Dispose();
                        rec1.Dispose();
                        rec2.Dispose();
                        bright.Dispose();
                        dark.Dispose();
                        System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                        {
                            CameraGCStyle0 = new Tuple<string, object>("Color", "red");
                            CameraGCStyle0 = new Tuple<string, object>("DrawMode", "fill");
                            CameraAppendHObject0 = r_region;
                            CameraAppendHMessage0 = new HMsgEntry($"亮色:{brightp:p1}\n暗色:{dartp:p1}", 10, 300, _coordSystem: "window", _genParamName: new HTuple().TupleConcat("box_color"), _genParamValue: new HTuple().TupleConcat("firebrick"),
                                           _color: "white", _Size: 18);
                            if (r1 && r2)
                            {
                                CameraAppendHMessage0 = new HMsgEntry("OK", 10, 10, _coordSystem: "window", _genParamName: new HTuple().TupleConcat("box_color"), _genParamValue: new HTuple().TupleConcat("green"),
                                                          _color: "white", _Size: 22);
                            }
                            else
                            {
                                CameraAppendHMessage0 = new HMsgEntry("NG", 10, 10, _coordSystem: "window", _genParamName: new HTuple().TupleConcat("box_color"), _genParamValue: new HTuple().TupleConcat("red"),
                                                       _color: "white", _Size: 22);
                            }
                        }));
                    }).ContinueWith(arg => { IsBusy = false; });

                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show("图像为空", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        async void ExecuteGrabImageCommand()
        {
            IsCameraReady = false;
            var r = await GrabImage(10000);
            if (r)
            {
                if (mimage != null)
                {
                    mimage.Dispose();
                }
                _camera.ImageQueue.TryDequeue(out mimage);
                CameraImage0 = new HImage(mimage.CopyObj(1, -1));
            }
            IsCameraReady = true;
        }
        void ExecuteOpenImageCommand()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "Image Files|*.png;*.bmp;*.jpg;*.tif";
            if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (mimage != null)
                {
                    mimage.Dispose();
                }
                HOperatorSet.ReadImage(out mimage, openFileDialog.FileName);
                CameraImage0 = new HImage(mimage.CopyObj(1, -1));
                LoadRegionInit();
            }
        }
        #endregion
        #region 导航
        public override void OnDialogClosed()
        {
            if (isChanged)
            {
                aggregator.SendMessage("ReloadParam", "Run");
            }
            isClosing = true;
            HIOCancelDraw();
        }
        public override void OnDialogOpened(IDialogParameters parameters)
        {
            handIndex = parameters.GetValue<int>("HandIndex");
            partNum = parameters.GetValue<string>("PartNum");
            if (partNum == null)
            {
                Task.Run(() =>
                {
                    //System.Threading.Thread.Sleep(100);
                    System.Windows.Application.Current.Dispatcher.Invoke(new Action(() =>
                    {
                        OnRequestClose(new Prism.Services.Dialogs.DialogResult(ButtonResult.Cancel));
                    }));
                });
                return;
            }
            switch (handIndex)
            {
                case 0:
                    _camera = _containerProvider.Resolve<ICameraService>("LeftCamera");
                    Title = "左相机算法";
                    break;
                default:
                    _camera = _containerProvider.Resolve<ICameraService>("RightCamera");
                    Title = "右相机算法";
                    break;
            }
            IsCameraReady = _camera.m_bIsDeviceOpen;
            LoadFromDb();

        }
        #endregion
        #region 构造函数
        public CameraVisionDialogViewModel(IContainerProvider containerProvider) : base(containerProvider)
        {
            IsBusy = false;
            DrawROIOperateList.Add(new DrawROIOperateDisp
            {
                IconPath = "/MResources/Images/联集.png",
                OperateName = "合并"
            });
            DrawROIOperateList.Add(new DrawROIOperateDisp
            {
                IconPath = "/MResources/Images/交集.png",
                OperateName = "交集"
            });
            DrawROIOperateList.Add(new DrawROIOperateDisp
            {
                IconPath = "/MResources/Images/差集.png",
                OperateName = "差集"
            });
            //DrawROIOperateList.Add(new DrawROIOperateDisp
            //{
            //    IconPath = "/MResources/Images/减去顶层.png",
            //    OperateName = "XOR"
            //});
            DrawROIOperateListSelectedIndex = 0;
            RegionColorKind = 0;
            _containerProvider = containerProvider;

            drawROI = containerProvider.Resolve<DrawROI>();
            aggregator.ResgiterMessage(arg =>
            {
                string[] strs = arg.Message.Split(new char[] { ';' });
                switch (strs[0])
                {
                    case "PartNumChanged":
                        {
                            partNum = strs[1];
                            LoadFromDb();
                        }
                        break;
                    default:
                        break;
                }
            }, "Run");
        }
        #endregion
        #region 功能函数
        async Task<bool> GrabImage(int timeout)
        {
            bool restult = false;
            while (_camera.ImageQueue.Count > 0)
            {
                _camera.ImageQueue.TryDequeue(out var image);
            }
            _camera.StartGrabe();
            Task task = new Task(() =>
            {
                while (_camera.ImageQueue.Count == 0) Thread.Sleep(20);
            });
            var delay = Task.Delay(timeout);
            task.Start();
            if (await Task.WhenAny(task, delay) == delay)
            {
                restult = false;
            }
            else
            {
                restult = true;
            }
            _camera.StopGrabe();
            return restult;
        }
        private void LoadFromDb()
        {
            using var mdb = new MDbContext();
            var _param = mdb.MParams.FirstOrDefault(p => p.Name == "MaxGrayDark" && p.Hand == handIndex && p.PartNum == partNum);
            if (_param != null)
            {
                var r = int.TryParse(_param.Value, out var v1);
                if (r)
                {
                    MaxGrayDark = v1;
                }
            }
            else
            {
                MaxGrayDark = 50;
                mdb.MParams.Add(new MParam
                {
                    Name = "MaxGrayDark",
                    Value = MaxGrayDark.ToString(),
                    Hand = handIndex,
                    PartNum = partNum
                });
                mdb.SaveChanges();
            }

            _param = mdb.MParams.FirstOrDefault(p => p.Name == "MinGrayLight" && p.Hand == handIndex && p.PartNum == partNum);
            if (_param != null)
            {
                var r = int.TryParse(_param.Value, out var v1);
                if (r)
                {
                    MinGrayLight = v1;
                }
            }
            else
            {
                MinGrayLight = 200;
                mdb.MParams.Add(new MParam
                {
                    Name = "MinGrayLight",
                    Value = MinGrayLight.ToString(),
                    Hand = handIndex,
                    PartNum = partNum
                });
                mdb.SaveChanges();
            }

            _param = mdb.MParams.FirstOrDefault(p => p.Name == "BrightAreaMin" && p.Hand == handIndex && p.PartNum == partNum);
            if (_param != null)
            {
                var r = double.TryParse(_param.Value, out var v1);
                if (r)
                {
                    BrightAreaMin = v1;
                }
            }
            else
            {
                BrightAreaMin = 0.1;
                mdb.MParams.Add(new MParam
                {
                    Name = "BrightAreaMin",
                    Value = BrightAreaMin.ToString(),
                    Hand = handIndex,
                    PartNum = partNum
                });
                mdb.SaveChanges();
            }
            _param = mdb.MParams.FirstOrDefault(p => p.Name == "DarkAreaMin" && p.Hand == handIndex && p.PartNum == partNum);
            if (_param != null)
            {
                var r = double.TryParse(_param.Value, out var v1);
                if (r)
                {
                    DarkAreaMin = v1;
                }
            }
            else
            {
                DarkAreaMin = 0.1;
                mdb.MParams.Add(new MParam
                {
                    Name = "DarkAreaMin",
                    Value = DarkAreaMin.ToString(),
                    Hand = handIndex,
                    PartNum = partNum
                });
                mdb.SaveChanges();
            }
        }
        private void LoadRegionInit()
        {
            CameraAppendHObject0 = null;
            if (CameraImage0 != null)
            {
                switch (RegionColorKind)
                {
                    case 0:
                        {
                            CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                            CameraGCStyle0 = new Tuple<string, object>("Color", "blue");
                            string dirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, partNum, $"Camera\\{handIndex}");
                            Directory.CreateDirectory(dirPath);
                            if (File.Exists(System.IO.Path.Combine(dirPath, "Rec1.hobj")))
                            {
                                HOperatorSet.ReadRegion(out var rec1, System.IO.Path.Combine(dirPath, "Rec1.hobj"));
                                CameraAppendHObject0 = rec1;
                            }
                        }
                        break;
                    case 1:
                        {
                            CameraGCStyle0 = new Tuple<string, object>("DrawMode", "margin");
                            CameraGCStyle0 = new Tuple<string, object>("Color", "red");
                            string dirPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, partNum, $"Camera\\{handIndex}");
                            Directory.CreateDirectory(dirPath);
                            if (File.Exists(System.IO.Path.Combine(dirPath, "Rec2.hobj")))
                            {
                                HOperatorSet.ReadRegion(out var rec1, System.IO.Path.Combine(dirPath, "Rec2.hobj"));
                                CameraAppendHObject0 = rec1;
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
        }
        #endregion
    }
}
